package com.diligent.cloud.sfc.factory.impl;

import com.alibaba.fastjson.JSON;
import com.canny.commons.model.ObjectResult;
import com.canny.commons.model.Result;
import com.canny.commons.page.IPage;
import com.canny.commons.page.Pagination;
import com.diligent.cloud.primary.data.feign.service.imat.IMatImageFeignService;
import com.diligent.cloud.primary.data.feign.service.mdm.MdmMatTypeFeignService;
import com.diligent.cloud.primary.data.model.mdm.MdmMatType;
import com.diligent.cloud.primary.data.model.rt.RtWorkCenter;
import com.diligent.cloud.sfc.factory.StationFactory;
import com.diligent.cloud.sfc.model.MatType;
import com.diligent.cloud.sfc.model.OrderType;
import com.diligent.cloud.sfc.model.detail.WearStripsDetailInfo;
import com.diligent.cloud.sfc.model.enums.MatStatus;
import com.diligent.cloud.sfc.model.info.WearStripsInfo;
import com.diligent.cloud.sfc.service.ISfcService;
import com.diligent.cloud.sfc.service.impl.WipServiceImpl;
import com.diligent.cloud.web.model.PageAndCondition;
import com.diligent.cloud.wip.core.feign.service.WipStorageLedgerFeignService;
import com.diligent.cloud.wip.core.vo.StorageLedgerInfo;
import com.diligent.cloud.wip.panel.modle.WipStorageLedger;
import com.diligent.cloud.workorder.enums.WoOrderStatus;
import com.diligent.cloud.workorder.model.MatNeedGroupByMatCode;
import com.diligent.cloud.workorder.model.WoOrder;
import com.diligent.cloud.workorder.model.WoOrderCompleteDetail;
import com.diligent.cloud.workorder.model.WoOrderMatNeed;
import com.diligent.cloud.workorder.service.WoOrderFeignService;
import com.diligent.cloud.workorder.service.WoOrderMatNeedFeignService;
import com.diligent.foundation.data.model.v2.Condition;
import com.google.common.base.Preconditions;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;

/**
 * WearStripsStation class
 *
 * @author xf107278
 * @date 4/3/2020
 */
@Component
public class WearStripsStation implements StationFactory {
    private ISfcService sfcService;

    private WoOrderFeignService orderFeignService;

    private final MdmMatTypeFeignService mdmMatTypeFeignService;

    private final WoOrderMatNeedFeignService orderMatNeedFeignService;

    private final WipServiceImpl wipServiceImpl;

    private final IMatImageFeignService matImageFeignService;
    private final WipStorageLedgerFeignService wipStorageLedgerFeignService;
    private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");


    public WearStripsStation(ISfcService sfcService,
                             WoOrderFeignService orderFeignService,
                             MdmMatTypeFeignService mdmMatTypeFeignService,
                             WoOrderMatNeedFeignService orderMatNeedFeignService, WipServiceImpl wipServiceImpl,
                             IMatImageFeignService matImageFeignService,
                             WipStorageLedgerFeignService wipStorageLedgerFeignService) {
        this.sfcService = sfcService;
        this.orderFeignService = orderFeignService;
        this.mdmMatTypeFeignService = mdmMatTypeFeignService;
        this.orderMatNeedFeignService = orderMatNeedFeignService;
        this.wipServiceImpl = wipServiceImpl;
        this.matImageFeignService = matImageFeignService;
        this.wipStorageLedgerFeignService = wipStorageLedgerFeignService;
    }

    /***
     * 1. 同型号未完成工单(根据Dps日排查计划)
     *      未完成
     *      未完成支数<30
     * 2. 子型号配套率
     * 3. 胶条备料进度
     *      查询当天工作时间需要的配料率
     *      查询同工单胶条的备料率
     *
     * @param order
     * @return
     */
    @Override
    public Result getOrderInfo(WoOrder order) {


        WearStripsDetailInfo wearStripsDetailInfo = new WearStripsDetailInfo();

        //查询到所有当前信息工单

        String stripsType = sfcService.getMatType(MatType.胶条);
        String matType = sfcService.getMatType(MatType.虚拟物料);

        //未完成同胶条工单
        Integer sameMatUnfinishedOrder = 0;
        //未完成工单
        Integer unfinishedOrder = 0;
        //穿条信息
        List<WearStripsInfo> wearStripsInfos = new ArrayList<>();

        //查询当班胶条
        long time1 = System.currentTimeMillis();

        wearStripsDetailInfo.setGumStripsStock(getOnDutySchedule(stripsType, order));
        long time2 = System.currentTimeMillis();
        System.out.println("当前程序耗时：" + (time2 - time1) + "ms");

        //同型号胶条
        wearStripsDetailInfo.setGumStrips(getSameMatSchedule(order.getCv7(), order));

        //子型号(当班)
        wearStripsDetailInfo.setSubModelStock(getOnDutySchedule(matType, order));
        //子型号(同胶)
        ArrayList<LinkedHashMap> sameMatNeedMap =
                ( (  ArrayList<LinkedHashMap>) orderMatNeedFeignService.selectSameMatNeed(order.getMachineCode(), order.getCv7(), matType,
                        order.getOrderType().toString(), simpleDateFormat.format(order.getProduceDate())).getBody().getData());
        wearStripsDetailInfo.setSubModelSameGumStock(getDigit(order,sameMatNeedMap));


//        getUnfinishedOrder();


        ResponseEntity<com.diligent.cloud.primary.data.model.Result> orderResult =
                orderFeignService.selectById(order.getId());
        for (WoOrderMatNeed woOrderMatNeed : ((WoOrder) orderResult.getBody().getData()).getOrderMatNeeds()) {

            if (!matType.equalsIgnoreCase(woOrderMatNeed.getMatType())) {
                continue;
            }
            WearStripsInfo wearStripsInfo = new WearStripsInfo();

            wearStripsInfo.setMatCode(woOrderMatNeed.getMatCode());
            //需求数
            wearStripsInfo.setRequireDigit(woOrderMatNeed.getDigit());
            //库存数
            wearStripsInfo.setStockDigit(((WipStorageLedger) (wipServiceImpl.getInventoryByMatCodeAndCwocCode(woOrderMatNeed.getMatCode(),
                    order.getWorkCenterCode(), woOrderMatNeed.getCv1(), order.getSystemId()).getBody().getData())).getDigit().intValue());
            //图片
            wearStripsInfo.setImage((String) matImageFeignService.getMouldPic(woOrderMatNeed.getMatCode()).getBody().getData());
            //添加显示信息
            wearStripsInfos.add(wearStripsInfo);
            //TODO 在产数？
            PageAndCondition pageAndCondition = new PageAndCondition();
            ArrayList<Condition> conditions = new ArrayList<>();
            pageAndCondition.setPagination(new Pagination(1L, 1000000L));
            conditions.add(new Condition("orderType", "eq", OrderType.挤压工单, null));
            conditions.add(new Condition("orderStatus", "eq", MatStatus.processing.getStatus(), null));
            conditions.add(new Condition("matCode", "eq", woOrderMatNeed.getMatCode(), null));

            pageAndCondition.setConditions(conditions);
            ResponseEntity<com.diligent.cloud.primary.data.model.Result<IPage<WoOrder>>> orderPage =
                    orderFeignService.page(pageAndCondition);
            wearStripsInfo.setProduceDigit(0L);
            for (WoOrder woOrder : orderPage.getBody().getData().getRecords()) {
                wearStripsInfo.setProduceDigit(wearStripsInfo.getProduceDigit() + woOrder.getDeliveryDigit().longValue());
            }

        }


        wearStripsDetailInfo.setSameMatUnfinishedOrder(getSameMatCodeOrder(order,"cv7",order.getCv7(), WoOrderStatus.schedulings.getStatus()));
        wearStripsDetailInfo.setUnfinishedOrder(unfinishedOrder);
        wearStripsDetailInfo.setOrderLength(Long.valueOf(order.getCv4()));
        wearStripsDetailInfo.setWearStripsPlanNumber(order.getDeliveryDigit().longValue());
        wearStripsDetailInfo.setWearStripsInfos(wearStripsInfos);
        wearStripsDetailInfo.setWearStripsCompleteNumber(0L);
        wearStripsDetailInfo.setWearStripsGoodNumber(0L);

        return new ObjectResult<>(wearStripsDetailInfo);
    }



    Long getOnDutySchedule(String matType, WoOrder order) {
        ArrayList<LinkedHashMap> onDutyStripsMap =
                ((ArrayList<LinkedHashMap>) orderMatNeedFeignService.selectMatNeedDigitSumGroupByOrderDate(matType,
                        order.getOrderType().toString(), simpleDateFormat.format(order.getProduceDate()),
                        order.getMachineCode()).getBody().getData());

        return getDigit(order, onDutyStripsMap);
    }

    Long getSameMatSchedule(String matCode, WoOrder order) {
        ResponseEntity<com.diligent.cloud.primary.data.model.Result> sameGumResult =
                orderMatNeedFeignService.selectMatNeedDigitSumGroupByMatCode(matCode,
                        simpleDateFormat.format(order.getProduceDate()), order.getMachineCode());
        if (sameGumResult.getBody().getData()!=null){

        Double demandDigit = ((MatNeedGroupByMatCode) sameGumResult.getBody().getData()).getSumDigit();
        int stockDigit = ((WipStorageLedger) (wipServiceImpl.getInventoryByMatCodeAndCwocCode
                (order.getCv7(),
                        order.getWorkCenterCode(), null, order.getSystemId())
                .getBody().getData())).getDigit().intValue();
        if (stockDigit != 0) {
            return new Double((demandDigit / stockDigit) * 100).longValue();
        } else {
            return 0L;
        } }
         return 0L;
    }

    void getUnfinishedOrder() {
        PageAndCondition pageAndCondition = new PageAndCondition();
        List<Condition> conditions = new ArrayList<>();
        conditions.add(new Condition("machineCode", "eq", "D2001", null));
        conditions.add(new Condition("enterCode", "eq", "2020-06-09", null));
        conditions.add(new Condition("systemId", "eq", "1", null));
        conditions.add(new Condition("isCanceled", "eq", "0", null));
        conditions.add(new Condition("isClosed", "eq", "0", null));

        pageAndCondition.setPagination(new Pagination(1L, 10000L));
        pageAndCondition.setConditions(conditions);

        ResponseEntity<com.diligent.cloud.primary.data.model.Result<IPage<WoOrder>>> page =
                orderFeignService.page(pageAndCondition);
        int unfinishedOrder = 0;
        for (WoOrder woOrder : page.getBody().getData().getRecords()) {
            WoOrderCompleteDetail orderCompleteByOrder = sfcService.getOrderCompleteByOrder(woOrder.getId(),
                    woOrder.getWoOrder());
            if (orderCompleteByOrder == null) {
                continue;
            }
            if (orderCompleteByOrder.getDigit().intValue() < 30) {
                unfinishedOrder++;
            }
        }
        System.out.printf(String.valueOf(unfinishedOrder));
    }
     Long getSameMatCodeOrder(WoOrder order,String properties,String matCode,Integer orderStatus){
        PageAndCondition pageAndCondition = new PageAndCondition();
        List<Condition> conditions = new ArrayList<>();
        pageAndCondition.setPagination(new Pagination(1L,1L));

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        conditions.add(new Condition("orderType","eq",order.getOrderType(),null));
        conditions.add(new Condition("orderStatus","eq",orderStatus,null));
        conditions.add(new Condition("produceDate","eq",simpleDateFormat.format(order.getProduceDate()),null));
        conditions.add(new Condition("systemId","eq",order.getSystemId(),null));
        conditions.add(new Condition(String.format("%s",properties),"eq",matCode,null));
        conditions.add(new Condition("machineCode","eq",order.getMachineCode(),null));

        pageAndCondition.setConditions(conditions);

        ResponseEntity<com.diligent.cloud.primary.data.model.Result<IPage<WoOrder>>> page =
                orderFeignService.page(pageAndCondition);
        return page.getBody().getData().getTotal();

    }

    Long getDigit(WoOrder order,ArrayList<LinkedHashMap> var1) {
        Double total = new Double("0");
        List<StorageLedgerInfo> storageLedgerInfos = new ArrayList<>();
        RtWorkCenter workCenter = sfcService.getWorkCenterByCwocCode(order.getWorkCenterCode());
        StorageLedgerInfo storageLedgerInfo;
        for (LinkedHashMap map : var1) {
            MatNeedGroupByMatCode matNeedResult = JSON.parseObject(JSON.toJSONString(map), MatNeedGroupByMatCode.class);

            storageLedgerInfo = new StorageLedgerInfo();
            storageLedgerInfo.setMatCode(matNeedResult.getMatCode());
            storageLedgerInfos.add(storageLedgerInfo);

            total += matNeedResult.getSumDigit();
        }
        ObjectResult<WipStorageLedger> collectLedger =
                wipStorageLedgerFeignService.getCollectLedger(order.getSystemId(), workCenter.getStorageCode(),
                        storageLedgerInfos);


        if (collectLedger.getData().getDigit().intValue() != 0) {

            return new Double((collectLedger.getData().getDigit().intValue() / total) * 100).longValue();
        } else {
            return 0L;
        }
    }

}
